package com.geline.word.starter;

import com.geline.word.constants.HtmlToWordConstants;
import com.geline.word.util.Word2HtmlUtil;
import com.geline.word.util.WordUtils;
import com.geline.word.util.XWPFDocumentUtil;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * word处理Service类
 * @author: mengxin
 * @date: 2022/10/20 9:47
 */
public class SdkWordService {
    private static final Logger log = LoggerFactory.getLogger(SdkWordService.class);

    private SdkWordProperties sdkWordProperties;

    public SdkWordService(SdkWordProperties sdkWordProperties){
        this.sdkWordProperties = sdkWordProperties;
        String rootPath = sdkWordProperties.getRootPath();
        if(rootPath.indexOf("${user.dir}") != -1){
            //替换变量：${user.dir}
            sdkWordProperties.setRootPath(rootPath.replace("${user.dir}", System.getProperty("user.dir")));
        }
    }

    /**
     * 上传word并返回生成的html文件
     * @param multipartFile
     * @return
     * @throws IOException
     * @throws TransformerException
     * @throws ParserConfigurationException
     */
    public File uploadWord2Html(String id, MultipartFile multipartFile) throws IOException, TransformerException, ParserConfigurationException {
        if (!multipartFile.isEmpty()) {
            String rootPath = sdkWordProperties.getRootPath();
            File dir = new File(rootPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            String filename = multipartFile.getOriginalFilename();
            if (filename.endsWith(HtmlToWordConstants.DOC)) {
                return Word2HtmlUtil.docToHtml(multipartFile, rootPath, id);
            } else if (filename.endsWith(HtmlToWordConstants.DOCX)) {
                return Word2HtmlUtil.docxToHtml(multipartFile, rootPath, id);
            } else {
                throw new RuntimeException("格式有误，只允许doc,docx的word文件");
            }
        }
        return null;
    }

    /**
     * 解析html并导出word-docx文件
     * @param fileName
     * @param htmlText
     * @param request
     * @param response
     * @throws IOException
     * @throws InvalidFormatException
     */
    public void downDocxByHtml(String fileName, String htmlText, HttpServletRequest request, HttpServletResponse response) throws IOException, InvalidFormatException {
        String urlHeader = sdkWordProperties.getUrlHeader();
        //由于刚刚导入解析存储的是相对路径，所以导出时要加上图片资源的前缀，我这里直接存储在了自定义的静态资源目录中
        String content = Word2HtmlUtil.replaceImgSrc(urlHeader, htmlText);
        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("word/content.docx");
        OPCPackage srcPackage = OPCPackage.open(in);
        XWPFDocument doc = new XWPFDocument(srcPackage);

        List<Map<String, Object>> mapList = new ArrayList<>();
        Map<String, Object> param = new HashMap<>(16);
        param.put("content", content);
        mapList.add(param);
        XWPFDocumentUtil.wordInsertRichText(doc, mapList);
        // 将docx输出
        WordUtils.exportWordList(doc, fileName, request, response);
    }

    /**
     * 获取生成的html预览地址
     * @param id
     * @return
     */
    public String getPreviewUrl(String id){
        String urlHeader = sdkWordProperties.getUrlHeader();
        return urlHeader+(urlHeader.endsWith("/") ? "words/" : "/words/")+id+"/index.html";
    }

    /**
     * 删除word上传的资源目录
     * @param id
     */
    public void deleteUploadFile(String id){
        String rootPath = sdkWordProperties.getRootPath();
        File uploadFile = new File(rootPath+"words/"+id);
        if(uploadFile.isDirectory()){
            boolean b = uploadFile.delete();
            log.info("deleteUploadFile : {} = {}", uploadFile.getAbsolutePath(), b);
        }
    }
}
